package 进阶阶段;

/**
 * 创建人：刘源江
 * 类描述：
 * 创建时间：2022/9/12 23:06
 **/

public class demo30函数式接口 {
    public static void main(String[] args) {
        //函数式接口：有且仅有一个抽象方法的接口
        //函数式接口，即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda，所以函数式接口就是可
        //以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法，Java中的Lambda才能顺利地进行推导。

        System.out.println("无参无返回的函数式接口-----------------------");
        //匿名内部类，通过new父类对象找到儿子对象
        m1(new Eatable(){
            @Override
            public void eat() {
                System.out.println("吃个鸡腿！");
            }
        });

        //lambda表达式 ()->{}
        m1(()->{
            System.out.println("lambda表达式写法：吃个鸡腿");
        });

        System.out.println("有参有返回的函数式接口-----------------------");
        //匿名内部类，通过new父类对象找到儿子对象
        m2(new Sumable() {
            @Override
            public int sum(int a, int b) {
                return a+b;
            }
        });

        //lambda表达式 ()->{}
        m2((int a, int b)->{
            return a+b;
        });

        //Lambda的延迟执行,解决性能浪费
        //当满足条件时才执行，不满足条件时不执行操作，避免了资源的浪费
        System.out.println("Lambda的延迟执行-----------------------------");
        log(2, new Sumable() {//level参数为2，没有调用log方法
            @Override
            public int sum(int a, int b) {
                return a+b;
            }
        });

        log(1 , (int a, int b)->{//level参数为1，调用log方法
            return a-b;
        });

        System.out.println("Lambda作为参数返回值-------------------------");
        m1(get1());

        m2(get2());
    }

    public static void m1(Eatable e){
        e.eat();
    }

    public static void m2(Sumable s){
        int i = s.sum(2 , 3);
        System.out.println(i);
    }

    public static void log(int level , Sumable s){
        if (level == 1){
            System.out.println("执行了操作");
            int i = s.sum(2 , 3);
            System.out.println(i);
        }
    }

    public static Eatable get1(){
        Eatable e = () -> {
            System.out.println("Lambda作为参数返回值：吃个鸡腿");
        };
        return e;
    }

    public static Sumable get2(){
        Sumable s = (int a, int b) -> {
            return a * b;
        };
        return s;
    }
}

//无参无返回函数式接口
//定义一个函数式接口Eatable，内含抽象eat方法，没有参数或返回值。使用该接口作为方法的参数，并进而通过Lambda来使用它
//@FunctionalInterface注解：表示特别注意解释这个是函数式接口，并编译检测受否是一个抽象方法
@FunctionalInterface
interface Eatable{
    void eat();
}

//自定义有参有返回的函数式接口
//定义一个函数式接口Sumable，内含抽象sun方法，可以将两个int数字相加返回int结果，使用该接口作为某个
//方法的参数，并进而通过lambda来使用它
interface Sumable{
    int sum(int a , int b);
}